﻿Imports Microsoft.VisualBasic
Imports System
Imports System.IO
Imports System.Text
Imports System.Security.Cryptography
Imports log4net

Public Class ProjectTools
    Private Shared ReadOnly log As ILog = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType)

    Shared passPhrase As String = "LiveryCoach"
    Shared saltValue As String = "LiveryCoach"
    Shared hashAlgorithm As String = "SHA1" ' can be "MD5"
    Shared passwordIterations As Integer = 2
    Shared initVector As String = "@1B2c3D4e5F6g7H8" '"@LiveryCoach!56@" ' must be 16 bytes
    Shared keySize As Integer = 256 ' can be 128, 192, or 256

    ''Encryto by AES  ------------------------------------------------------------------------------
    Private Const _strKey As String = "@1B2c3D4e5F6g7H8"
    Private Const _blockSize As Integer = 128
    Private Const _keySize As Integer = 128
    ''0: CipherMode.CBC
    ''1: CipherMode.CFB
    ''2: CipherMode.CTS
    ''3: CipherMode.ECB
    ''4: CipherMode.OFB
    Private Const _cipherModeType As Integer = 0

    ''1: Security.Cryptography.PaddingMode.None
    ''2: Security.Cryptography.PaddingMode.PKCS7
    ''3: Security.Cryptography.PaddingMode.Zeros
    ''4: Security.Cryptography.PaddingMode.ANSIX923
    ''5: Security.Cryptography.PaddingMode.ISO10126
    Private Const _paddingMode As Integer = 2

    Public Shared Function getDataFromFile(ByVal sFile As String) As String
        Dim fs As FileStream
        Dim sr As StreamReader

        getDataFromFile = ""
        Try
            fs = New FileStream(sFile, FileMode.Open)
            sr = New StreamReader(fs)

            getDataFromFile = sr.ReadToEnd
            fs.Close()
        Catch ex As Exception
            getDataFromFile = ex.Message
        End Try
    End Function

    Public Shared Function Encrypt(ByVal plainText As String) As String

        Dim initVectorBytes As Byte()
        initVectorBytes = Encoding.ASCII.GetBytes(initVector)

        Dim saltValueBytes As Byte()
        saltValueBytes = Encoding.ASCII.GetBytes(saltValue)

        Dim plainTextBytes As Byte()
        plainTextBytes = Encoding.UTF8.GetBytes(plainText)

        Dim password As PasswordDeriveBytes
        password = New PasswordDeriveBytes(passPhrase, saltValueBytes, hashAlgorithm, passwordIterations)

        Dim keyBytes As Byte()
        keyBytes = password.GetBytes(keySize / 8)

        Dim symmetricKey As RijndaelManaged
        symmetricKey = New RijndaelManaged()
        symmetricKey.Mode = CipherMode.CBC

        Dim encryptor As ICryptoTransform
        encryptor = symmetricKey.CreateEncryptor(keyBytes, initVectorBytes)

        Dim memoryStream As MemoryStream
        memoryStream = New MemoryStream()

        Dim cryptoStream As CryptoStream
        cryptoStream = New CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write)
        cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length)

        cryptoStream.FlushFinalBlock()

        Dim cipherTextBytes As Byte()
        cipherTextBytes = memoryStream.ToArray()

        memoryStream.Close()
        cryptoStream.Close()

        Dim cipherText As String
        cipherText = Convert.ToBase64String(cipherTextBytes)

        Encrypt = Replace(cipherText, "+", "[[ADD]]")
        Encrypt = Replace(Encrypt, "&", "[[AMPERSAND]]")
    End Function

    Public Shared Function Decrypt(ByVal cipherText As String) As String

        Dim initVectorBytes As Byte()
        initVectorBytes = Encoding.ASCII.GetBytes(initVector)

        Dim saltValueBytes As Byte()
        saltValueBytes = Encoding.ASCII.GetBytes(saltValue)

        ' Convert our ciphertext into a byte array.
        Dim cipherTextBytes As Byte()

        cipherText = Replace(cipherText, "[[ADD]]", "+")
        cipherText = Replace(cipherText, "[[AMPERSAND]]", "&")
        cipherTextBytes = Convert.FromBase64String(cipherText)

        Dim password As PasswordDeriveBytes
        password = New PasswordDeriveBytes(passPhrase, saltValueBytes, hashAlgorithm, passwordIterations)

        Dim keyBytes As Byte()
        keyBytes = password.GetBytes(keySize / 8)

        Dim symmetricKey As RijndaelManaged
        symmetricKey = New RijndaelManaged()
        symmetricKey.Mode = CipherMode.CBC

        Dim decryptor As ICryptoTransform
        decryptor = symmetricKey.CreateDecryptor(keyBytes, initVectorBytes)

        Dim memoryStream As MemoryStream
        memoryStream = New MemoryStream(cipherTextBytes)

        Dim cryptoStream As CryptoStream
        cryptoStream = New CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read)
        Dim plainTextBytes As Byte()
        ReDim plainTextBytes(cipherTextBytes.Length)

        Dim decryptedByteCount As Integer
        decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length)

        memoryStream.Close()
        cryptoStream.Close()

        Dim plainText As String
        plainText = Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount)

        Decrypt = plainText
    End Function

    Public Shared Function getParameterValue(ByVal sParameter As String, ByVal sTag As String, Optional ByVal iType As Integer = 0) As String
        Dim sTokens() As String = Split(sParameter, "&")
        Dim iCtr As Integer

        On Error Resume Next
        getParameterValue = ""
        If iType = 1 Then
            getParameterValue = "0"
        End If

        For iCtr = 0 To sTokens.Length - 1
            Select Case True
                Case InStr(UCase(sTokens(iCtr)), UCase(sTag & "=")) > 0
                    getParameterValue = Split(sTokens(iCtr), "=")(1)
            End Select
            If getParameterValue > "" Then
                Exit For
            End If
        Next
    End Function

    'Dim plainText As String
    'Dim cipherText As String

    'Dim passPhrase As String
    'Dim saltValue As String
    'Dim hashAlgorithm As String
    'Dim passwordIterations As Integer
    'Dim initVector As String
    'Dim keySize As Integer

    'plainText          = "Hello, World!"    ' original plaintext

    'passPhrase         = "Pas5pr@se"        ' can be any string
    'saltValue          = "s@1tValue"        ' can be any string
    'hashAlgorithm      = "SHA1"             ' can be "MD5"
    'passwordIterations = 2                  ' can be any number
    'initVector         = "@1B2c3D4e5F6g7H8" ' must be 16 bytes
    'keySize            = 256                ' can be 192 or 128

    'Console.WriteLine(String.Format("Plaintext : {0}", plainText))

    'cipherText = RijndaelSimple.Encrypt(plainText,          _
    '                                    passPhrase,         _
    '                                    saltValue,          _
    '                                    hashAlgorithm,      _
    '                                    passwordIterations, _
    '                                    initVector,         _
    '                                    keySize)

    'Console.WriteLine(String.Format("Encrypted : {0}", cipherText))

    'plainText  = RijndaelSimple.Decrypt(cipherText,         _
    '                                    passPhrase,         _
    '                                    saltValue,          _
    '                                    hashAlgorithm,      _
    '                                    passwordIterations, _
    '                                    initVector,         _
    '                                    keySize)

    'Console.WriteLine(String.Format("Decrypted : {0}", plainText))

#Region "ASE"

    Public Shared Function EncryptDataByAES(ByVal plainText As String) As String
        Dim cipherText As String = ""
        Try
            cipherText = plainText
            If Not plainText.Trim.Equals("") Then
                Using acsp As AesCryptoServiceProvider = GetProvider(Encoding.Default.GetBytes(_strKey))
                    Dim sourceBytes() As Byte = Encoding.UTF8.GetBytes(plainText)
                    Dim ictE As ICryptoTransform = acsp.CreateEncryptor()
                    Dim msS As MemoryStream = New MemoryStream()
                    Dim csS As New Security.Cryptography.CryptoStream(msS, ictE, CryptoStreamMode.Write)
                    csS.Write(sourceBytes, 0, sourceBytes.Length)
                    csS.FlushFinalBlock()
                    Dim encryptedBytes() As Byte = msS.ToArray()

                    cipherText = Convert.ToBase64String(encryptedBytes)
                    msS.Dispose()

                    cipherText = Replace(cipherText, "+", "[[ADD]]")
                    cipherText = Replace(cipherText, "&", "[[AMPERSAND]]")
                End Using
            End If
        Catch ex As Exception
            log.Error(ex)
            cipherText = ""
        End Try
        Return cipherText
    End Function

    Public Shared Function DecryptDataByAES(ByVal cipherText As String) As String
        Dim plainText As String = ""
        Try
            plainText = cipherText
            If Not cipherText.Trim.Equals("") Then
                cipherText = Replace(cipherText, "[[ADD]]", "+")
                cipherText = Replace(cipherText, "[[AMPERSAND]]", "&")

                Using acsp As AesCryptoServiceProvider = GetProvider(Encoding.Default.GetBytes(_strKey))
                    Dim rawBytes() As Byte = Convert.FromBase64String(cipherText)
                    Dim ictD As ICryptoTransform = acsp.CreateDecryptor()
                    Dim msD As MemoryStream = New MemoryStream(rawBytes, 0, rawBytes.Length)
                    Dim csD As New Security.Cryptography.CryptoStream(msD, ictD, CryptoStreamMode.Read)
                    plainText = (New StreamReader(csD)).ReadToEnd()
                    msD.Dispose()
                End Using
            End If
        Catch ex As Exception
            log.Error(ex)
            plainText = ""
        End Try
        Return plainText
    End Function

    Private Shared Function GetProvider(ByVal key() As Byte) As AesCryptoServiceProvider
        Dim result As New AesCryptoServiceProvider()
        result.BlockSize = _blockSize
        result.KeySize = _keySize
        Select Case _cipherModeType
            Case 0
                result.Mode = CipherMode.CBC
            Case 1
                result.Mode = CipherMode.CFB
            Case 2
                result.Mode = CipherMode.CTS
            Case 3
                result.Mode = CipherMode.ECB
            Case 4
                result.Mode = CipherMode.OFB
            Case Else
                result.Mode = CipherMode.CBC
        End Select

        Select Case _paddingMode
            Case 1
                result.Padding = Security.Cryptography.PaddingMode.None
            Case 2
                result.Padding = Security.Cryptography.PaddingMode.PKCS7
            Case 3
                result.Padding = Security.Cryptography.PaddingMode.Zeros
            Case 4
                result.Padding = Security.Cryptography.PaddingMode.ANSIX923
            Case 5
                result.Padding = Security.Cryptography.PaddingMode.ISO10126
            Case Else
                result.Padding = Security.Cryptography.PaddingMode.None
        End Select

        result.GenerateIV()
        Dim arrIV() As Byte = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
        result.IV = arrIV
        result.Key = GetKey(key, result)

        Return result
    End Function

    Private Shared Function GetKey(ByVal suggestedKey() As Byte, ByVal p As Security.Cryptography.SymmetricAlgorithm) As Byte()

        Dim kRaw() As Byte = suggestedKey
        Dim kList As New List(Of Byte)
        For i As Integer = 0 To p.LegalKeySizes(0).MinSize - 1 Step 8
            kList.Add(kRaw((i / 8) Mod kRaw.Length))
        Next
        Dim k() As Byte = kList.ToArray()
        Return k
    End Function


#End Region

#Region "LiveryCoachCer"

    Public Shared Function IsActivatedLiveryCoachCer() As Integer
        Dim iCount As Integer = 0
        Try
            Dim sql As String = "select count(*) from sys.symmetric_keys where name = 'CCENDE_KEY_01'"
            iCount = Connection.ExcuteScalar(sql, True)

        Catch ex As Exception
            Connection.CheckCloseConnect()
            log.Error(ex)
        End Try
        Return iCount
    End Function

    Public Shared Sub OpenSymmetric()
        Try
            Connection.ExcuteQuery(" open symmetric key CCENDE_KEy_01 decryption by certificate LiveryCoachCer; ")
        Catch ex As Exception
            log.Error(ex)
        End Try
    End Sub

    'Public Shared Function DecryptByLiveryCoachCer(ByVal encryptedccData As String) As String
    '    Dim plaintext As String = ""
    '    Try
    '        Dim sql As String = "BEGIN TRANSACTION DecryptByLiveryCoachCer "
    '        sql = String.Format("{0} open symmetric key CCENDE_KEy_01 decryption by certificate LiveryCoachCer; ", sql)
    '        sql = String.Format("{0} select convert(varchar(50), decryptbykey('{1}')); ", sql, encryptedccData)
    '        sql = String.Format("{0} COMMIT", sql)
    '        plaintext = Connection.ExcuteScalar(sql, True)
    '        'Using reader As SqlDataReader = Connection.ExcuteReader(sql)
    '        '    If reader.Read AndAlso reader.HasRows Then
    '        '        plaintext = reader(0)
    '        '    End If
    '        'End Using
    '        'Connection.Close()
    '    Catch ex As Exception
    '        Connection.CheckCloseConnect()
    '        log.Error(ex)
    '    End Try
    '    Return plaintext
    'End Function

#End Region

End Class
